/**
 * Class Name: MatrixActivity
 * Description: 
 *
 * @author Sultan-PC
 * @version 1.00
 * @date Feb 20th, 2011
 * 
**/

package com.matrix.calculator;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;

import com.matrix.math.ColumnVector;
import com.matrix.utilities.Parser;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

public class Matrix extends Activity
{
	/**
	 * Instance Variables
	 */
	private Spinner operations;
	private EditText et1, et2, et3;
	private Button view1, view2, view3, calculate;
	private ArrayAdapter aa;
	private String currentOp, errorMsg;
	private Parser parser;
	private double det;
	private GlobalVars gvars;
	
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.matrix);
		this.initiate();
	}
	
    public void initiate()
    {
		parser = new Parser();
    	this.aa = ArrayAdapter.createFromResource(
                this, R.array.matrix_ops, android.R.layout.simple_spinner_item);
    	this.aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    	this.operations = (Spinner) this.findViewById(R.id.spinner);
    	
    	gvars = GlobalVars.getInstance();
    	
    	this.et1 = (EditText) this.findViewById(R.id.edit_matrixA);
    	this.et2 = (EditText) this.findViewById(R.id.edit_matrixB);
    	this.et3 = (EditText) this.findViewById(R.id.edit_vectorB);
    	
    	this.view1 = (Button) this.findViewById(R.id.btn1);
    	this.view2 = (Button) this.findViewById(R.id.btn2);
    	this.view3 = (Button) this.findViewById(R.id.btn3);
    	this.calculate = (Button) this.findViewById(R.id.btn4);
    	
    	this.setAdapters();
    	this.addListeners();
    }
    
    public void setAdapters()
    {
    	this.operations.setAdapter(aa);
    }
    public void addListeners()
    {
       this.view1.setOnClickListener(new OnClickListener(){
    		public void onClick(View v)
    		{
    			//gets the string in the textbox if the string is empty then 
    			//pop up a dialog box asking them to insert the matrix
    			String s = et1.getText().toString();
    			if(s.equals(""))
    			{
    				errorMsg = "Please Insert the Matricies.";
    				showDialog(0);
    				return;
    			}
    			//uses the parser to get the matrix out of the string
    			double[][] d;
				try {
					d = parser.getMatrix(s);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					errorMsg = e.getMessage();
     				showDialog(-1);
     				return;
				}
     			//creates and Intent which is used to pass information to other activities 
    			Intent myIntent = new Intent(v.getContext(), ResultView.class);
    			myIntent.putExtra("OP", 8);
    			myIntent.putExtra("view", 0);
    			ArrayList<com.matrix.math.Matrix> m = new ArrayList<com.matrix.math.Matrix>();
    			m.add(new com.matrix.math.Matrix("A", d));
    			gvars.setResultMatrices(m);
 			   	//starts the activity as a sub activity
 			   	startActivityForResult(myIntent, 0);
    			
    		}
    	});
       this.view2.setOnClickListener(new OnClickListener()
       {
    	   public void onClick(View v)
    	   {
    		   //gets the string in the textbox if the string is empty then 
    		   //pop up a dialog box asking them to insert the matrix
    		   String s = et2.getText().toString();
    		   if(s.equals(""))
    		   {
    			   errorMsg = "Please Insert the Matricies.";
    			   showDialog(0);
    			   return;
    		   }
    		   //uses the parser to get the matrix out of the string
    		   double[][] d;
    		   try {
    			   d = parser.getMatrix(s);
    		   } catch (Exception e) {
    			   errorMsg = e.getMessage();
    			   showDialog(-1);
    			   return;
    		   }
    		   //creates and Intent which is used to pass information to other activities 
    		   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    		   myIntent.putExtra("OP", 8);
    		   myIntent.putExtra("view", 1);
    		   ArrayList<com.matrix.math.Matrix> m = new ArrayList<com.matrix.math.Matrix>();
    		   m.add(new com.matrix.math.Matrix("B", d));
    		   gvars.setResultMatrices(m);
    		   //starts the activity as a sub activity
    		   startActivityForResult(myIntent, 0);
    	   }
       });
       this.view3.setOnClickListener(new OnClickListener()
       {
    	   public void onClick(View v)
    	   {
    		   // similar to view 1 except using a vector
    		   String s = et3.getText().toString();
    		   if(s.equals(""))
    		   {
    			   errorMsg = "Please Insert the Vector.";
    			   showDialog(-5);
    			   return;
    		   }
    		   double[] d;
    		   try {
    			   d = parser.getVector(s);
    		   } catch (Exception e) {
    			   // TODO Auto-generated catch block
    			   errorMsg = e.getMessage();
    			   showDialog(-1);
    			   return;
    		   }
    		   ArrayList<ColumnVector> a = new ArrayList<ColumnVector>();
    		   a.add(new ColumnVector("b", d));
    		   gvars.setResultVectors(a);
    		   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    		   myIntent.putExtra("OP", 8);
    		   myIntent.putExtra("view", 2);
    		   startActivityForResult(myIntent, 0);
    	   }
       });
       this.calculate.setOnClickListener(new OnClickListener()
       {
    	   public void onClick(View v)
    	   {
    		   String s = et1.getText().toString();
			   String s2 = et2.getText().toString();
    		   // check to see what operation the user selected
    		   // inside is similar to that of the views
    		   if(currentOp.equals("Heat Map"))
    		   {
    			   double[][] d;
        		   try {
        			   d = parser.getMatrix(s);
        		   } catch (Exception e) {
        			   // TODO Auto-generated catch block
        			   errorMsg = parser.error;
        			   showDialog(-1);
        			   return;
        		   }
    			   Intent myIntent = new Intent(v.getContext(), HeatMap.class);
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", d);
    			   GlobalVars.getInstance().addResultMatrix(a);
    			   startActivityForResult(myIntent, 0); 
    		   }
    		   else if(currentOp.equals("Multiplication"))
    		   {
    			   if(s.equals("")||s2.equals(""))
    			   {
    				   errorMsg = "Please Insert the Matricies.";
    				   showDialog(0);
    				   return;
    			   }
    			   double[][] m1;
    			   try {
    				   m1 = parser.getMatrix(s);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   double[][] m2;
    			   try {
    				   m2 = parser.getMatrix(s2);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   if(m1[0].length!=m2.length)
    			   {
    				   errorMsg = "Matrix B must have the same number of rows as Matrix A's number of columns";
    				   showDialog(-4);
    				   return;
    			   }
    			   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    			   myIntent.putExtra("OP", 0);
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", m1);
    			   com.matrix.math.Matrix b = new com.matrix.math.Matrix("B", m2);
    			   try {
    				   com.matrix.math.Matrix temp = a.multMatrix(b);
    				   GlobalVars.getInstance().addResultMatrix(temp);
    			   } catch (Exception e) {
    				   errorMsg = e.getMessage();
    				   showDialog(-10);
    				   return;
    			   }
    			   startActivityForResult(myIntent, 0);
    		   }
    		   else if(currentOp.equals("Addition"))
    		   {
    			   if(s.equals("")||s2.equals(""))
    			   {
    				   errorMsg = "Please Insert the Matricies.";
    				   showDialog(0);
    				   return;
    			   }
    			   double[][] m1;
    			   try {
    				   m1 = parser.getMatrix(s);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   double[][] m2;
    			   try {
    				   m2 = parser.getMatrix(s2);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   if(m1.length!=m2.length||m1[0].length!= m2[0].length)
    			   {
    				   errorMsg = "The Matrices dimensions are not the same.";
    				   showDialog(-3);
    				   return;
    			   }
    			   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    			   myIntent.putExtra("OP", 0);
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", m1);
    			   com.matrix.math.Matrix b = new com.matrix.math.Matrix("B", m2);
    			   try {
    				   com.matrix.math.Matrix temp = a.add(b);
    				   GlobalVars.getInstance().addResultMatrix(temp);
    			   } catch (Exception e) {
    				   errorMsg = e.getMessage();
    				   showDialog(-10);
    				   return;
    			   }
    			   startActivityForResult(myIntent, 0);
    		   }
    		   else if(currentOp.equals("Transpose"))
    		   {
    			   double[][] m;
    			   try {
    				   m = parser.getMatrix(s);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", m);
    			   try {
    				   com.matrix.math.Matrix temp = a.transpose();
    				   GlobalVars.getInstance().addResultMatrix(temp);
    			   } catch (Exception e) {
    				   errorMsg = e.getMessage();
    				   showDialog(-10);
    				   return;
    			   }
    			   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    			   myIntent.putExtra("OP", 0);
    			   startActivityForResult(myIntent, 0);
    		   }
    		   else if(currentOp.equals("Inverse"))
    		   {
    			   double[][] m;
    			   try {
    				   m = parser.getMatrix(s);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", m);
    			   try {
    				   com.matrix.math.Matrix temp = a.inverse();
    				   GlobalVars.getInstance().addResultMatrix(temp);
    			   } catch (Exception e) {
    				   errorMsg = e.getMessage();
    				   showDialog(-10);
    				   return;
    			   }
    			   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    			   myIntent.putExtra("OP", 0);
    			   startActivityForResult(myIntent, 0);
    		   }
    		   else if(currentOp.equals("Determinant"))
    		   {
    			   double[][] m;
    			   try {
    				   m = parser.getMatrix(s);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", m);
    			   try {
    				   double d = a.determinant();
    				   det = d;
    				   showDialog(1);
    			   } catch (Exception e) {
    				   errorMsg = e.getMessage();
    				   showDialog(-10);
    				   return;
    			   }
    		   }
    		   else if(currentOp.equals("P-L-U Factorization"))
    		   {
    			   double[][] m;
    			   try {
    				   m = parser.getMatrix(s);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", m);
    			   try {
    				   GlobalVars.getInstance().setResultMatrices(a.pluFactorization());
    			   } catch (Exception e) {
    				   errorMsg = e.getMessage();
    				   showDialog(-10);
    				   return;
    			   }
    			   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    			   myIntent.putExtra("OP", 5);
    			   startActivityForResult(myIntent, 0);
    		   }
    		   else if(currentOp.equals("Null Space"))
    		   {
    			   double[][] m;
    			   try {
    				   m = parser.getMatrix(s);
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", m);
    			   try {
    				   GlobalVars.getInstance().setResultVectors(a.nullSpace());
    			   } catch (Exception e) {
    				   errorMsg = e.getMessage();
    				   showDialog(-10);
    				   return;
    			   }
    			   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    			   myIntent.putExtra("OP", 10);
    			   startActivityForResult(myIntent, 0);
    		   }
    		   else if(currentOp.equals("Ax = b solving for x"))
    		   {
    			   String s3 = et3.getText().toString();
    			   double[][] m;
    			   double[] v1;
    			   try {
    				   m = parser.getMatrix(s);
    				   v1 = parser.getVector(s3);
    				   
    			   } catch (Exception e1) {
    				   errorMsg = e1.getMessage();
    				   showDialog(-1);
    				   return;
    			   }
    			   com.matrix.math.Matrix a = new com.matrix.math.Matrix("A", m);
    			   ColumnVector b = new ColumnVector("b", v1);
    			   try {
    				   GlobalVars.getInstance().setResultVectors(a.axbSolve(b));
    			   } catch (Exception e) {
    				   errorMsg = e.getMessage();
    				   showDialog(-10);
    				   return;
    			   }
    			   Intent myIntent = new Intent(v.getContext(), ResultView.class);
    			   myIntent.putExtra("OP", 6);
    			   startActivityForResult(myIntent, 0);
    		   }
    	   }
       });
       //creates a listener for the spinner/combo box to get which item was selected by the user 
       this.operations.setOnItemSelectedListener(new OnItemSelectedListener()
       {

    	   public void onItemSelected(AdapterView<?> parent,
    	   View view, int pos, long id) 
       	   {
       			currentOp = parent.getItemAtPosition(pos).toString();
       	   }

       	   public void onNothingSelected(AdapterView<?> parent) {
       		   // Do nothing.
       	   }
       });
       
    }// end AddListeners()
    //creates a dialog box
    protected Dialog onCreateDialog(int id)
    {
    	if(id <= 0)
    	{
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(errorMsg)
            .setCancelable(false)
            .setPositiveButton("Ok", new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog, int id) {
            
            }
            });
            AlertDialog alert = builder.create();
            alert.setTitle("Error");
    		return alert;
    	}
    	else
    	{
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(""+det)
            .setCancelable(false)
            .setPositiveButton("Ok", new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog, int id) {
            
            }
            });
            AlertDialog alert = builder.create();
            alert.setTitle("Determinant");
    		return alert;
    	}
    	
    }
    
}// end Class